/**
 * 处理表头列分页Worker版
 * @param {any[]} funcArgs 函数参数
 * @param {Object} defines 变量定义
 */
export function getPagesColumnWorker(funcArgs, defines) {
  const { pageBaseInfo } = defines
  const cloneDeep = obj => JSON.parse(JSON.stringify(obj))

  /**
   * @description 表头横向分页优化算法
   * @param {*} tree 旧树
   * @param {*} nextNode 下一个待分配叶子节点
   * @param {*} fullMap 全量节点 map
   * @returns {Object}
   *    {isNew} nextNode 与 tree 的关系
   *    {pushWidth} isNew为true时, 推入pushWidth宽度
   *    {nextWidth} nextWidth isNew为true时, 新树的宽度
   *    {tree} 每次生成的树, 可能为新树, 也可能为旧树, 但总是可信的, 可重复传传递给方法首参 tree
   */
  function optimizeColumnsWidthCost(tree, nextNode, fullMap) {
    function isNew(tree, insetNode, fullMap) {
      if (!tree) {
        return true
      }
      if (!insetNode) {
        return true
      }
      if (!insetNode._pUuid) {
        return true
      }
      /**
       * @description BFS查找节点, 找到返回true, 否则为false
       * @param {*} sTree 查找树
       * @param {*} node 查找节点
       * @returns
       */
      const bfs = (sTree, node) => {
        if (!sTree || !node) {
          return false
        }
        if (sTree._uuid === node._uuid) {
          return true
        }
        const childList = sTree._childList || []
        for (const childNode of childList) {
          const result = bfs(childNode, node)
          if (result) {
            return true
          }
        }
        return false
      }

      // * 查看当前节点是否在
      if (bfs(tree, insetNode)) {
        return false
      }

      let upUuid = insetNode._pUuid
      while (upUuid) {
        // ! 如果 upNode 为空值, 不应该出现这种情况
        const upNode = fullMap.get(upUuid)
        const result = bfs(tree, upNode)
        if (result) {
          return false
        }

        upUuid = upNode._pUuid // 向上追溯
      }
      return true
    }

    // * 计算树的宽度
    const getTreeCostWidth = tree => {
      // console.log(tree)
      if (!tree) {
        return 0
      }
      const widthList = []
      widthList.push(tree._width)

      const childList = tree._childList || []
      let childWidth = 0
      for (const child of childList) {
        childWidth += getTreeCostWidth(child)
      }
      widthList.push(childWidth)

      return Math.max(...widthList)
    }

    /**
     * @description 构造原始树
     * @param {*} node
     * @param {*} fullMap
     * @returns
     */
    const buildTree = (node, fullMap) => {
      let tree = null

      let searchUuid = node._uuid
      while (searchUuid) {
        const searchNode = cloneDeep(fullMap.get(searchUuid))
        if (searchUuid) {
          Object.assign(searchNode, { childNode: [], jgtChild: [] })
          searchNode._childList = []

          if (!tree) {
            tree = searchNode
          } else {
            searchNode._childList.push(tree)
            tree = searchNode
          }
        }
        // ? 防止死循环
        searchUuid = searchNode ? searchNode._pUuid : null
      }
      return tree
    }

    const nodeInsertTree = (tree, insertNode, fullMap) => {
      if (tree._uuid === insertNode._pUuid) {
        !Array.isArray(tree._childList) && (tree._childList = [])
        tree._childList.push(
          Object.assign(cloneDeep(insertNode), { childNode: [], jgtChild: [] })
        )
        return tree
      }
      const childList = tree._childList || []
      // 是否是新子节点的下层节点
      let isNewChildSubNode = true
      for (const child of childList) {
        // * 此处非常容易理解错误, 这里 isNew() 方法的期望返回为 false, 表示新节点属于某颗子树下 判断条件前应该加个 !
        if (!isNew(child, insertNode, fullMap)) {
          isNewChildSubNode = false
          nodeInsertTree(child, insertNode, fullMap)
        }
      }
      // * 此处 isNewChildSubNode 应为 true, 表示该节点目前不在当前子节点列表下
      if (isNewChildSubNode) {
        const childTree = buildTree(insertNode, fullMap)

        /**
         * @description 寻找目标节点的子节点列表
         * @param {*} tree
         * @param {*} targetNode
         * @returns
         */
        const findNodeChildList = (tree, targetNode) => {
          if (tree._uuid === targetNode._uuid) {
            return tree._childList || []
          }
          const childList = tree._childList || []
          for (const child of childList) {
            const result = findNodeChildList(child, targetNode)
            if (result.length) {
              return result
            }
          }
          return []
        }

        const newChildList = findNodeChildList(childTree, tree)

        // console.log("childTree, newChildList: ", childTree, newChildList, tree);

        !Array.isArray(tree._childList) && (tree._childList = [])
        for (const child of newChildList) {
          tree._childList.push(child)
        }
      }
      return tree
    }

    if (isNew(tree, nextNode, fullMap)) {
      const treeMaxWidth = getTreeCostWidth(tree)
      const newTree = buildTree(nextNode, fullMap)
      const newTreeMaxWidth = getTreeCostWidth(newTree)
      return {
        isNew: true,
        pushWidth: treeMaxWidth,
        nextWidth: newTreeMaxWidth,
        tree: newTree
      }
    }

    const newTree = nodeInsertTree(tree, nextNode, fullMap)
    const newTreeMaxWidth = getTreeCostWidth(newTree)

    return {
      isNew: false,
      pushWidth: newTreeMaxWidth,
      nextWidth: 0,
      tree: newTree
    }
  }

  /**
   * TODO 算法有待优化
   * @description 处理表头列分页
   * @param {*} leafMap
   * @param {*} tree
   * @param {*} pageInfo
   * @returns
   */
  function getPagesColumn(leafMap, tree, pageInfo = pageBaseInfo, fullMap) {
    const pagingResult = {
      pagesInfo: [],
      pagesColumn: []
    }
    let sumWidth = 0 // * 总渲染宽度
    const leafColumns = [] // * 全部的叶子节点
    const repeatColumns = []
    let repeatWidth = 0 // 重复渲染列宽度
    const pagesX = 1 // * 横向分页数
    for (const value of leafMap.values()) {
      sumWidth += value._width
      leafColumns.push(value)
      if (value._repeat) {
        repeatColumns.push(value)
        repeatWidth += value._width
      }
    }

    const pageList = []

    // * 横向不需要分页
    // if (sumWidth <= pageInfo.available.w) {
    //   pageList.push(cloneDeep(leafColumns));

    //   const pageInfo = {
    //     pageXWidth: sumWidth, // 页面宽度
    //   };
    //   pagingResult.pagesInfo.push(pageInfo);
    //   pagingResult.pagesColumn = pageList;
    //   console.log("pagingResult: ", pagingResult);
    //   return pagingResult;
    // }

    // // ! 该计算方式出现横向分页缺失几率较高
    // // * 当纸张横向可渲染空间 小于 渲染总长度
    // while (pagesX * pageInfo.available.w < sumWidth + repeatWidth * (pagesX - 1)) {
    //   pagesX = pagesX + 1; // 横向分页数 +1
    // }

    const pagesInfo = [] // * 分页信息
    const pages = [] // ? 横向分页数组 （原始数组, 需要二次处理）

    let allotCount = 0 // * 已分配的列数
    let p = 0
    while (allotCount < leafColumns.length) {
      const pageColumns = [] // 当前页
      let contentWidth = 0 // 当前页占据的宽度

      // * 从第二页开始, 将重复项推入, 占据的宽度也纳入计算
      if (p > 0) {
        pageColumns.push(...cloneDeep(repeatColumns))
        contentWidth = repeatWidth
      }

      let compareContentWidth = contentWidth // 修正的内容比较宽度
      let compareTree = null
      let prevResult = null
      for (let i = allotCount; i < leafColumns.length; ++i) {
        const iColumn = leafColumns[i]
        contentWidth += iColumn._width

        const nextNodeWidth = iColumn._dTreeMaxW || iColumn._width // 根据叶子节点纵深树的最大宽度来决定是否推入当前页面

        const result = optimizeColumnsWidthCost(compareTree, iColumn, fullMap)
        // console.log(result, iColumn)
        compareTree = result.tree

        /* console.log(
          "p, compareContentWidth, result, prevResult, pageBaseInfo.available.w: ",
          p,
          compareContentWidth,
          result,
          prevResult,
          pageBaseInfo.available.w
        ); */
        // TODO 代码较乱, 需要整理
        // * 分页算法已优化
        const curWidth =
          compareContentWidth + result.pushWidth + result.nextWidth
        if (!isNaN(parseFloat(curWidth)) && isFinite(curWidth)) {
        } else {
          ++allotCount
          break
        }
        if (curWidth <= pageInfo.available.w) {
          pageColumns.push(cloneDeep(iColumn))
          if (result.isNew) {
            compareContentWidth += result.pushWidth
          }
          ++allotCount
          if (allotCount === leafColumns.length) {
            // console.log("i, compareContentWidth, result: ", i, compareContentWidth, result);
            pagesInfo.push({
              pageXWidth: compareContentWidth + result.nextWidth
            })
          }
        } else {
          // * 处理开启下一分页前当前分页宽度计算
          let curPageWidth = compareContentWidth
          if (result.isNew) {
            curPageWidth += result.pushWidth
          } else {
            if (prevResult) {
              !prevResult.isNew &&
                !result.isNew &&
                (curPageWidth += prevResult.pushWidth) // ? 皆为新树时
              curPageWidth += prevResult.nextWidth
            }
          }
          pagesInfo.push({ pageXWidth: curPageWidth })
          compareTree = null
          ++p // 分页 +1
          break // 跳出当前循环
        }
        prevResult = result
      }
      pages.push(pageColumns)
    }

    pagingResult.pagesInfo = pagesInfo
    pagingResult.pagesColumn = pages

    // console.log("pagesInfo: ", pagesInfo);
    // console.log("pagesColumn：", pages);

    return pagingResult
  }

  return getPagesColumn(...funcArgs)
}
